热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

变量|批量_超多绑定变量导致异常的一个案例

篇首语:本文由编程笔记#小编为大家整理,主要介绍了超多绑定变量导致异常的一个案例相关的知识,希望对你有一定的参考价值。最近生产上出现一个问题,某个应用单个S

篇首语:本文由编程笔记#小编为大家整理,主要介绍了超多绑定变量导致异常的一个案例相关的知识,希望对你有一定的参考价值。


最近生产上出现一个问题,某个应用单个SQL中绑定变量个数超过了65535个,导致数据库出现了异常终止的现象。


通过trace,看到很多这样的信息(为了脱敏,此处引用MOS的例子),



导致问题的SQL诸如这种,


BEGIN
UPDATE TEST SET
C1 = :1,
C2 = :2,
C3 = :3,
C4 = :4,
C5 = :5,
C6 = :6,
C7 = :7
WHERE ID = :8 AND ACC = :9
;
UPDATE TEST SET
C1 = :10,
C2 = :11,
C3 = :12,
C4 = :13,
C5 = :14,
C6 = :15,
C7 = :16
WHERE ID = :17 AND ACC = :18
;
UPDATE TEST SET
C1 = :19,
C2 = :20,
C3 = :21,
C4 = :22,
C5 = :23,
C6 = :24,
C7 = :25
WHERE ID = :26 AND ACC = :27
;
...
UPDATE TEST SET
C1 = :619001,
C2 = :619002,
C3 = :619003,
C4 = :619004,
C5 = :619005,
C6 = :619006,
C7 = :619007,
WHERE ID = :619008 AND ACC = :619009
; END;

这是一段PL/SQL,其中批量拼接了很多的update,1条SQL是9个变量,总共六十多万个,粗略算下来,应该是6万多条SQL,显然他的逻辑是一次性更新6万多条记录。


此时问题有两个,


(1) 执行一次SQL为什么带着这么多绑定变量?


(2) 为什么执行这么多绑定变量的SQL会导致数据库出现问题?


MOS的这篇文章《Instance crashed after ORA-7445 [opiaba] and ORA-600 [17147] (Doc ID 1466343.1)》给出了第二个问题的答案,



如果在同一条SQL或PL/SQL语句中使用超过65535个绑定变量,则数据库实例会因为ORA-7445的错误导致出现ORA-600,进而异常中断。


官方给出的方案,是打个12578873的patch,但是他只会解决因为绑定变量超多导致的实例终止的问题,超过65535绑定变量的语句还是不能执行,因此无论是workaround,还是终极解决,都是建议不要使用绑定变量超过65535个,这就回到了第一个问题,超过65535个绑定变量的场景,合理么?


其实针对这案例,60多万个绑定变量,不是应用“有意而为之”的,他想做的是一次性批量更新6万多记录,但是他在MyBatis的mapper中用的是for-each,这就会循环遍历list,"BEGIN"开头,";END"结尾,";"作为separator,拼接出的PL/SQL,一次性执行,




UPDATE TEST SET
C1 = #item.c1,
C2 = #item.c2,
C3 = #item.c3,
C4 = #item.c4,
C5 = #item.c5,
C6 = #item.c6,
C7 = #item.c7
WHERE ID = #item.id AND ACC = #item.acc


P. S. 关于MyBatis的for-each,可以参考官方文档的介绍,



https://mybatis.org/mybatis-3/zh/dynamic-sql.html


如果要批量更新这些数据,该怎么做?


官网介绍了,应该用的是openSession时指定参数ExecutorType.BATCH,他将批量执行所有的更新语句,



https://mybatis.org/mybatis-3/zh/java-api.html#sqlSessions


mapper就是单条update语句,



openSession指定了ExecutorType.BATCH,并且设置了1000条更新执行一次提交的逻辑,



P. S. MyBatis工程的构建,可以参考《MyBatis Generator的使用和坑》。


从数据库端看,执行如下SQL,不再出现上万个绑定变量的情况,


UPDATE TEST SET
C1 = :1,
C2 = :2,
C3 = :3,
C4 = :4,
C5 = :5,
C6 = :6,
C7 = :7
WHERE ID = :8 AND ACC = :9;

以上才是真正的批量更新操作,从上面的操作,还可知道原始的BEGIN ... END的PL/SQL需要执行所有的update语句才提交一次,不是批量提交,算是一个隐患,这种拼接SQL,只适合小数据量的操作。


有同学讨论说怎么避免这种问题?这就可能有很多路径了,一个是开发规范中可以将这种坑实时更新进来,让设计开发人员有所了解,数据审核平台,则可以从技术层面验证这种“海量”绑定变量的场景,归根结底,这个问题考验的还是设计开发人员对MyBatis以及绑定变量的理解,如果只是会用,在很多场景下,能得到正确结果,但是碰到这种极端的场景,就会进坑。


因此在设计开发过程中,有些环节,还是要知道原理,虽然说殊途同归,但是可能某些路径会消耗更高的成本,或者产生更多的问题,这就要持续积累,持续避坑了。


近期更新的文章:


《学习工行MySQL研发管控和治理实践的过程》


《MyBatis Generator的使用和坑》


《缓存一致性解决方案介绍》


《从球衣了解“红魔”曼联历史》


《MySQL中SQL执行慢的一种可能的原因场景》


文章分类和索引:


《公众号900篇文章分类和索引》


推荐阅读
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 本文汇集了我在网络上搜集以及在实际面试中遇到的前端开发面试题目,并附有详细解答。无论是初学者还是有一定经验的开发者,都应深入理解这些问题背后的原理,通过系统学习和透彻研究,逐步形成自己的知识体系和技术框架。 ... [详细]
  • 如何在您的计算机上配置Python和PyCharm开发环境
    本文详细介绍了在Windows 10系统上配置Python和PyCharm开发环境的步骤。内容包括Python的安装与卸载、PyCharm的安装与卸载,以及如何在Windows 10中通过双击安装文件“python-3.7.2-amd64.exe”来完成Python的安装。此外,还提供了关于环境变量配置和基本设置的实用建议,帮助用户快速搭建高效的开发环境。 ... [详细]
  • 为开发者提供了一系列实用的参考网站和资源链接,包括HTML速查手册( 和 ),帮助开发者快速查找和学习相关技术知识。此外,还涵盖了其他重要的开发工具和文档,为编程工作提供全面支持。 ... [详细]
  • 该大学网站采用PHP和MySQL技术,在校内可免费访问某些外部收费资料数据库。为了方便学生校外访问,建议通过学校账号登录实现免费访问。具体方案可包括利用学校服务器作为代理,结合身份验证机制,确保合法用户在校外也能享受免费资源。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 如何优化MySQL数据库性能以提升查询效率和系统稳定性 ... [详细]
  • 在当今的软件开发领域,分布式技术已成为程序员不可或缺的核心技能之一,尤其在面试中更是考察的重点。无论是小微企业还是大型企业,掌握分布式技术对于提升工作效率和解决实际问题都至关重要。本周的Java架构师实战训练营中,我们深入探讨了Kafka这一高效的分布式消息系统,它不仅支持发布订阅模式,还能在高并发场景下保持高性能和高可靠性。通过实际案例和代码演练,学员们对Kafka的应用有了更加深刻的理解。 ... [详细]
  • 在这篇文章中,我们将深入探讨MySQL在某些情况下为什么会选择错误的索引,并从专业角度进行详细分析。通过丰富的案例和理论依据,帮助读者理解这一现象的原因及优化策略,提升数据库性能。 ... [详细]
  • 在深入研究 UniApp 封装请求时,发现其请求 API 方法中使用了 `then` 和 `catch` 函数。通过详细分析,了解到这些函数是 Promise 对象的核心组成部分。Promise 是一种用于处理异步操作的结果的标准化方式,它提供了一种更清晰、更可控的方法来管理复杂的异步流程。本文将详细介绍 Promise 的基本概念、结构和常见应用场景,帮助开发者更好地理解和使用这一强大的工具。 ... [详细]
  • 在 Vue 应用开发中,页面状态管理和跨页面数据传递是常见需求。本文将详细介绍 Vue Router 提供的两种有效方式,帮助开发者高效地实现页面间的数据交互与状态同步,同时分享一些最佳实践和注意事项。 ... [详细]
  • 本文详细探讨了JavaScript中数组去重的各种方法,并通过实际代码示例进行了深入解析。文章首先介绍了几种常见的去重技术,包括使用Set对象、过滤方法和双重循环等。每种方法都附有具体的实现代码,帮助读者更好地理解和应用这些技术。此外,文中还讨论了不同方法在性能上的优劣,为开发者提供了实用的参考。 ... [详细]
author-avatar
awrjftyitik
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有